林明進老師:「可以成為一顆大樹,就不要只作一片葉子。」 我想,鍊成鐵人應該是比變成大樹更酷的事。 ^^
鐵人賽
Templates
今天講Dagger如何在Activity應用
這篇是JAVA喔喔喔!
Q1:@Component?
A:因為前面有創全局應用共用的ApplicationComponent,所以在Activity創一個簡單的Component,並且是依賴在ApplicationComponent,等於也能拿到ApplicationComponent提供的功能OUO
然後跟自己的Module依賴,然後寫個inject讓後面在Activity容易注入
@MainActScoped
@Component(
dependencies = ApplicationComponent.class,
modules = {
MainModule.class
}
)
public interface MainComponent {
void inject(MainActivity mainActivity);
}
Q2:@MainActScoped?
A:這個是自定義Scoped,主要是讓他不同Scope的東西分開,可以想成在A Scope跟B Scope是不互通的,A拿A,B拿B提供,然後基本上所有Scope都是依賴Singleton的
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface MainActScoped {
}
Q3:@Module?
A:一樣提供activity跟context,然後因為我這是mvp,所以在這裡也會提供presenter,然後因為provide提供的有scope,所以module也是那個scope,所以component也必須是那個scope囉
@Module
public class MainModule {
private AppCompatActivity appCompatActivity;
public MainModule(AppCompatActivity appCompatActivity){
this.appCompatActivity=appCompatActivity;
}
@Provides
@MainActScoped
AppCompatActivity provideActivity(){
return appCompatActivity;
}
@Provides
@MainActScoped
Context provideContext(){
return appCompatActivity;
}
@Provides
@MainActScoped
MainContract.Presenter<MainContract.View> providePresenter(MainPresenter<MainContract.View> presenter) {
return presenter;
}
}
Q4.:@Provides?
A:provides就是要提供,提供你要提供給他也要標示inject,標示他是可以提供,可以注入的
如提供presenter,要在presenter下inject
@Inject 一般情況下是標注成員屬性和構造函數
標注的成員屬性不能是private,Dagger 2 還支持方法注入
@Inject還可以標注方法
Q:不能使用Inject?
A:不能使用的狀況有
* 介面沒有構造函數
*第三方repository/library的類不能被標注
*構造函數中的參數必須配置
public class MainPresenter <V extends MainContract.View> extends BasePresenter<V> implements MainContract.Presenter<V> {
/*@Inject 一般情況下是標注成員屬性和構造函數
標注的成員屬性不能是private,Dagger 2 還支持方法注入
@Inject還可以標注方法
*/
/**contract presenter -> implement (di goto true)
* contract view -> getView( )->getfun implement->activity
* attacher bind view*/
/*不能使用的狀況有
* 介面沒有構造函數
*第三方repository/library的類不能被標注
*構造函數中的參數必須配置
*/
@Inject
public MainPresenter(APIService apiService, CompositeDisposable compositeDisposable){
super(apiService,compositeDisposable);
}
@Override
public void getUserList() {
getView().showProgressDialog("loading");
/*CompositeDisposable 多個訂閱時使用 方便管理*/
getCompositeDisposable().add(getApiService()
.getUsers()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<List<Users>>() {
@Override
public void onNext(List<Users> value) {
getView().setData(value);
}
@Override
public void onError(Throwable e) {
Log.e("kk", "onError: "+e);
}
@Override
public void onComplete() {
getView().dismissProgressDialog();
}
}));
}
}
最後就是Activity啦!
第一個先將Compomnent綁入,下面applicationComponent也要寫因為你depency有用他(可以看mainComponent),
第二個要綁mainModule(要new他),第三步就是build起來了!!
@Component(
dependencies = ApplicationComponent.class,
modules = {
MainModule.class
}
)
mainComponent = DaggerMainComponent.builder()
.applicationComponent(((Application) getApplication()).getApplicationComponent())
.mainModule(new MainModule(this))
.build();
像之前有提供getApiService跟presenter,所以寫@Inject就可以注入使用了
public class MainActivity extends BaseActivity implements MainContract.View{
@Inject
APIService getApiService;
@Inject
MainContract.Presenter<MainContract.View> presenter;
public CompositeDisposable compositeDisposable;
private MainComponent mainComponent;
private TextView tv;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainComponent = DaggerMainComponent.builder()
.applicationComponent(((Application) getApplication()).getApplicationComponent())
.mainModule(new MainModule(this))
.build();
mainComponent.inject(this);
tv=findViewById(R.id.tv);
button=findViewById(R.id.button);
presenter.onAttached(this);
//getUserList();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.getUserList();
}
});
}
public void getUserList(){
getApiService.getUsers().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Users>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<Users> value) {
Log.e("tv", "onNext: "+value.get(0).getEmail() );
tv.setText(value.get(0).getUsername());
}
@Override
public void onError(Throwable e) {
Log.e("yy", "onError: "+e );
}
@Override
public void onComplete() {
}
});
}
@Override
public void setData(List<Users> usersList) {
Log.e("yy", "setData: "+usersList.get(0).getEmail());
tv.setText(usersList.get(0).getUsername());
}
}
大概就是這樣啦!